﻿using RPAVIEW.views.HomePages;
using RPAVIEW.views.loginAndRegist;
using RPAVIEW.views.OtherPages;
using SUNRPA.CONTROLS.IMPL.domain;
using SUNRPA.CONTROLS.IMPL.domain.constant;
using SUNRPA.CONTROLS.IMPL.util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.ExceptionServices;
using System.Windows;

namespace RPAVIEW {
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application {
        private static LogUtil logger = new LogUtil(typeof(App));
        public ScheduleUtil schedule;
        public UserInfo currentUser;
        public Dictionary<string, string> userDirs = new Dictionary<string, string>();
        public Dictionary<string, object> globalContainer = new Dictionary<string, object>();

        ~App() { 
            LogUtil.CloseLogger();
        }

        //启动
        private void StarpUp(object sender, StartupEventArgs e) {
            InitUserDir();
            //检查更新
            if(!CheckUpdate()) { 
                this.Shutdown();
                return;
            }
            //创建定时任务调度器
            schedule = ScheduleUtil.getInstance();
            globalContainer.Add(DefaultContents.QUARTZ_SCHEDULE, schedule);
            globalContainer.Add(DefaultContents.USER_DIRS, userDirs);
            RegistDel();
            LoginWindow rw = new LoginWindow();
            rw.Show();
        }

        //全局异常处理
        private void unHandleEx(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) {
            MessageBox.Show("系统错误：" + e.Exception.Message, "出现错误", MessageBoxButton.OK, MessageBoxImage.Warning);
            //记录日志（完善日志系统）
            e.Handled = true;
            logger.Error("系统错误：{em}", e.Exception, e.Exception.Message);
            if(!User32Utils.IsWindowVisible(Process.GetCurrentProcess().MainWindowHandle)) {
                this.Shutdown();
            }
        }

        private UserInfo GetUserInfo() { 
            return this.currentUser;
        }

        public object GetGlobalVar(string key) {
            if(this.globalContainer.ContainsKey(key)) { 
                 return this.globalContainer[key];
            } else { 
                return null;
            }
        }

        public void SetGlobalVar(string key, object value) {
            this.globalContainer.Add(key, value);
        }

        private void InitUserDir() { 
            string baseDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string level1 = baseDir + Path.DirectorySeparatorChar + "SUNRPA";
            string level2_cache = level1 + Path.DirectorySeparatorChar + "cache";
            string level2_custfile = level1 + Path.DirectorySeparatorChar + "custfile";
            string level2_log = level1 + Path.DirectorySeparatorChar + "log";
            string level2_update = level1 + Path.DirectorySeparatorChar + "update";
            string level3_eleLibrary = level2_custfile + Path.DirectorySeparatorChar + "eleLibrary";
            string level3_picLibrary = level2_custfile + Path.DirectorySeparatorChar + "picLibrary";
            userDirs.Add("parent", level1);
            userDirs.Add("cache", level2_cache);
            userDirs.Add("custfile", level2_custfile);
            userDirs.Add("log", level2_log);
            userDirs.Add("update", level2_update);
            userDirs.Add("eleLibrary", level3_eleLibrary);
            userDirs.Add("picLibrary", level3_picLibrary);
            foreach(string key in userDirs.Keys) { 
                string path = userDirs[key];
                if(!Directory.Exists(path)) { 
                    Directory.CreateDirectory(path);
                }
            }
        }
        
        private void RegistDel() { 
            FrontUiDelegateUtil.getUserInfoDel = new FrontUiDelegateUtil.GetUserInfoDel(this.GetUserInfo);
            FrontUiDelegateUtil.getGlobalVarDel = new FrontUiDelegateUtil.GetGlobalVarDel(this.GetGlobalVar);
            FrontUiDelegateUtil.ExeProcessDel = new FrontUiDelegateUtil.ExeProcess(AppPages.RunFromProcessInfo);
            FrontUiDelegateUtil.setGlobalVardel = new FrontUiDelegateUtil.SetGlobalVarDel(this.SetGlobalVar);
        }

        private bool CheckUpdate() {
            try { 
                //以后改成md5比较，只比较exe程序的md5值则可。每个exe都有一个代表自己version的属性来区别md5
                string currentVersion = SystemUtil.GetAPPConfig("CurrentVersion");
                HttpUtil httpUtil = HttpUtil.getInstance(SystemUtil.GetAPPConfig("ControlBaseIp") + SystemUtil.GetAPPConfig("UserUri"));
                HttpResponse<string> res = httpUtil.SendGet<string>("/checkUpdate", new Dictionary<string, string>() { { "version", currentVersion} });
                if(res.Code == 500) {
                    MessageBoxResult messResult = MessageBox.Show(res.Msg, "更新提示", MessageBoxButton.YesNo, MessageBoxImage.Information);
                    if(messResult == MessageBoxResult.Yes) {
                        logger.Info($"软件需要更新");
                        string updaterSavePath = $"{userDirs["update"]}{Path.DirectorySeparatorChar}SUNRPAUPDATER_{res.Data}.exe";
                        Stream stream = httpUtil.GetDownloadStream("/downLoadUpdater", null);
                        DownLoader downloader = new DownLoader(stream, updaterSavePath);
                        downloader.ShowDialog();
                        if(downloader.complete) {
                            //下载完成
                            ProcessStartInfo processInfo = new ProcessStartInfo(updaterSavePath, AppDomain.CurrentDomain.BaseDirectory);
                            Process updateProcess = Process.Start(processInfo);
                            User32Utils.SetForegroundWindow(updateProcess.MainWindowHandle);
                            return false;
                        } else { 
                            //下载未完成
                            throw new RpaBuildingException("下载未完成，退出程序");
                        }
                    } else { 
                        //不更新直接关闭，必须要更新
                        return false;
                    }
                } else {
                    return true;
                }
            }catch (Exception ex) {
                logger.Error("更新出现错误，程序退出！", ex);
                MessageBox.Show(ex.Message);
                return false;
            }
        }
    }
}
